package cn.jobstart.task;

import cn.jobstart.common.*;
import cn.jobstart.common.word.WordListen;
import cn.jobstart.common.word.WordUtils;
import cn.jobstart.es.listener.event.ResumeBaseEsAddAllEvent;
import cn.jobstart.modelExt.*;
import cn.jobstart.props.FileConfig;
import cn.jobstart.props.Street;
import cn.jobstart.pubInter.AbstractTask;
import cn.jobstart.pubInter.common.PageBean;
import cn.jobstart.pubInter.exception.SkException;
import cn.jobstart.searchExt.ResumeBasicSearchExt;
import cn.jobstart.service.*;
import cn.jobstart.vo.yy.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.deepoove.poi.XWPFTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
 * @author sunke
 * @version 1.0
 * @Description yy数据
 * @date 2023-10-30 14:26
 */


@EnableScheduling
@Slf4j
@Component
public class YYTask extends AbstractTask {


    private static final String RESUME_KEY = "pk5hlOAr=5Yt$1+3YEx-NlXI_h-%W%D#RNF6dbADH32nI%^cI8";
    static int limit = 10;
    private static final ExecutorService executor = Executors.newScheduledThreadPool(limit);
    private static final byte[] LOCK = new byte[0];
    // private  String url = "https://api.nbohrs.cn/front-gateway/person/noLogin/api/resumeList";
    private final String url = "http://192.168.30.60:9073/person/noLogin/api/resumeList";
    @Resource
    private IResumeBasicService resumeBasicService;
    @Resource
    private IPersonService personService;
    @Resource
    private IResumeEmploymentIntentionService resumeEmploymentIntentionService;
    @Resource
    private IResumeEducationalExperienceService resumeEducationalExperienceService;
    @Resource
    private IResumeWorkExperienceService resumeWorkExperienceService;
    @Resource
    private IResumeCertificateService resumeCertificateService;
    @Resource
    private IResumeProjectExperienceService resumeProjectExperienceService;
    @Resource
    private IResumeTrainingExperienceService resumeTrainingExperienceService;
    @Resource
    private IResumeCapabilityLabelService resumeCapabilityLabelService;
    @Resource
    private IResumeProfessionalSkillsService resumeProfessionalSkillsService;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Resource
    private FileConfig fileConfig;
    private List<Street> streetList;

    private boolean checkSignature(Long rnd, String signature) {
        if (StringUtil.isNullOrEmpty(rnd) || StringUtil.isNullOrEmpty(signature)) {
            return false;
        }
        return signature.equalsIgnoreCase(MD5.enCode(MD5.enCode(rnd + "") + RESUME_KEY + rnd));

    }

    private String createSignature(Long rnd) {
        return MD5.enCode(MD5.enCode(rnd + "") + RESUME_KEY + rnd);
    }

    /**
     * 任务
     */
    @Scheduled(cron = "0 58 23 * * ?")
    // @Scheduled(cron = "0 0/1 * * * ?")
    @Override
    public void run() {


        try {
            log.info("yy start");
            Long rnd = null;
            int pageSize = limit;
            int pageNumber = 1;

            List<FutureTask<Integer>> futureList = new ArrayList<>();
            String firstDayTime = YXDate.getFormatDate2String(YXDate.getTimeDayFirstSecond(new Date()));
            while (true) {
                try {

                    log.info("yy while run ----------");
                    rnd = System.currentTimeMillis();
                    JSONObject bodys = new JSONObject();
                    bodys.put("rnd", rnd);
                    bodys.put("signature", createSignature(rnd));
                    bodys.put("pageSize", pageSize);
                    bodys.put("pageNumber", pageNumber);
                    bodys.put("orderBy", "rp_person_resume.pr_create_time");
                    bodys.put("orderDesc", "desc");
                    bodys.put("orderBy1", "rp_person_resume.pr_id");
                    bodys.put("orderDesc1", "desc");
                    bodys.put("updateTimeStart", firstDayTime);


                    log.info("yy body:" + bodys.toJSONString());
                    String res = HttpTookit.doPostJson(url, bodys.toJSONString());
                    log.info("yy pageNumber:" + pageNumber);
                    log.info("yy res:" + res);
                    if (StringUtil.isNullOrEmpty(res)) {
                        pageNumber = pageNumber + 1;
                        continue;
                    }

                    JSONObject resultJson = JSONObject.parseObject(res);
                    if (!resultJson.getBoolean("success")) {
                        pageNumber = pageNumber + 1;
                        continue;
                    }
                    JSONObject dataJson = resultJson.getJSONObject("data");

                    rnd = dataJson.getLong("rnd");
                    String signature = dataJson.getString("signature");

                    if (!checkSignature(rnd, signature)) {
                        pageNumber = pageNumber + 1;
                        continue;
                    }


                    PageBean pageBean = dataJson.getJSONObject("page").toJavaObject(PageBean.class);
                    JSONArray listJsonArray = dataJson.getJSONArray("list");
                    if (StringUtil.isNullOrEmpty(listJsonArray)) {
                        pageNumber = pageNumber + 1;
                        continue;
                    }
                    int size = listJsonArray.size();

                    log.info("yy resume size:" + size);
                    for (int i = 0; i < size; i++) {
                        int finalI = i;

                        FutureTask<Integer> futureTask = new FutureTask<>(() -> {

                            try {
                                log.info("yy doRun start:" + finalI);
                                doRun(listJsonArray.getJSONObject(finalI));
                                log.info("yy doRun end :" + finalI);
                                return 1;
                            } catch (Exception e) {
                                return 0;
                            }


                        });
                        futureList.add(futureTask);
                        executor.submit(futureTask);

                    }


                    for (FutureTask<Integer> futureTask : futureList) {

                        try {
                            log.info("yy result:" + futureTask.get());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }
                    futureList.clear();
                    log.info("yy pageNumber:" + pageNumber);
                    pageNumber = pageNumber + 1;

                    Thread.sleep(5000);


                    if (pageBean.getCurrentPage() >= pageBean.getTotalPage()) {
                        return;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }


            }


        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    private void doRun(JSONObject jsonObject) {

        log.info("yy do run:");
        FullResumeVO vo = jsonObject.toJavaObject(FullResumeVO.class);


        if (StringUtil.isNullOrEmpty(vo)) {
            return;
        }

        log.info("yy do run vo mobile:" + vo.getBasic().getMobile());

        int integrity = NumberUtil.parseInt(vo.getBasic().getIntegrity(), 0);
        if (integrity < 60) {
            return;
        }

        synchronized (LOCK) {
            if (resumeBasicService.getCountBySearch(ResumeBasicSearchExt.getInstance().setOldResumesIdEq(vo.getBasic().getOldResumesId())) > 0) {
                log.info("yy do run exist:" + vo.getBasic().getOldResumesId());
                return;
            }
        }


        //设置简历文件
        vo.getBasic().setOldResumeFile(updateResumeFile(vo));

        //添加基础信息
        ResumeBasicExt resumeBasic = insertResumeBasic(vo);

        if (StringUtil.isNullOrEmpty(resumeBasic)) {
            log.info("yy resumeBasic: null");
            return;
        }


        String resumeId = resumeBasic.getId();
        String personId = resumeBasic.getPersonId();

        log.info("yy resumeId:" + resumeId);


        //求职意向
        insertIntention(vo, resumeId, personId);

        //教育经历
        insertEducation(vo, resumeId, personId);
        //工作经历
        insertWorkExperience(vo, resumeId, personId);
        //证书
        insertCertificate(vo, resumeId, personId);
        //项目经历
        insertProjectExperience(vo, resumeId, personId);
        //培训经历
        insertTrainingExperience(vo, resumeId, personId);
        //能力标签
        insertCapabilityLabel(vo, resumeId, personId);
        //技能
        insertProfessionalSkills(vo, resumeId, personId);


        //es
        ResumeBaseEsAddAllEvent esAddAllEvent = new ResumeBaseEsAddAllEvent();
        esAddAllEvent.setResumeId(resumeId);
        applicationEventPublisher.publishEvent(esAddAllEvent);

    }

    //下载简历文件
    private String updateResumeFile(FullResumeVO vo) {

        String fileUrl = vo.getBasic().getOldResumeFile();
        if (StringUtil.isNullOrEmpty(fileUrl)) {
            return "";
        }

        fileUrl = fileUrl.replace("https://api.nbohrs.cn/", "http://192.168.30.63/");
        fileUrl = fileUrl.replace("http://api.nbohrs.cn/", "http://192.168.30.63/");


        String suffix = FileUtil.getSuffix(fileUrl);
        String fileName = IdGen.uuid();
        String fullFilePath = fileConfig.getRoot() + File.separator + "resume" + File.separator + fileName + "." + suffix;
        try {
            DownloadURLFile.down(fileUrl, fileConfig.getRoot() + File.separator + "resume", "", fileName + "." + suffix);
        } catch (InterruptedException e) {

        }

        if(!"docx".equalsIgnoreCase(suffix) && !".doc".equalsIgnoreCase(suffix)){
            return fileName;
        }


        //说明已经下载完成 把一些信息做一下处理
        if (FileUtil.exists(fullFilePath)) {


            fileName=   modResume(fullFilePath, fileName, suffix);

        }


        return "resume/" + fileName + "." + suffix;


    }

    /**
     * 修改简历里的信息
     *
     * @param fullFilePath
     * @param fileName
     * @param suffix
     */
    public String modResume(String fullFilePath, String fileName, String suffix) {

        String targetFileName= fileName + "_1";
        try {


            WordUtils.createWord(fullFilePath, new FileOutputStream(new File(fileConfig.getRoot() + File.separator + "resume" + File.separator + targetFileName + "." + suffix)), null, null, new WordListen() {

                @Override
                public void receive(XWPFTemplate xwpfTemplate) {

                    List<Integer> removeRowIndex = SkList.getInstance();
                    XWPFTable table = null;
                    try {

                        table = xwpfTemplate.getXWPFDocument().getTables().get(0);

                        String title = xwpfTemplate.getXWPFDocument().getTables().get(0).getRow(0).getCell(0).getText();
                        if (!"报考信息".equalsIgnoreCase(title)) {
                            return;
                        }

                        removeRowIndex.add(0);

                        List<XWPFTableRow> rows = table.getRows();

                        for (int i = 0; i < rows.size(); i++) {

                            try {

                                String text = rows.get(i).getCell(0).getText().trim();

                                if ("报考考试".equalsIgnoreCase(text) || "报考单位".equalsIgnoreCase(text) || "报考职位".equalsIgnoreCase(text)

                                ) {
                                    removeRowIndex.add(i);
                                    continue;
                                }


                            } catch (Exception e) {


                            }


                        }


                    } catch (Exception e) {

                    }
                    if (StringUtil.isNotObjEmpty(removeRowIndex) && StringUtil.isNotObjEmpty(table)) {
                        int removeIndex = 0;
                        for (Integer i : removeRowIndex) {
                            table.removeRow(i.intValue() - removeIndex);
                            removeIndex = removeIndex + 1;
                        }


                    }
                }

            });
        } catch (FileNotFoundException e) {
            return fileName;
        }


        return targetFileName;

    }

    /**
     * 技能专长
     *
     * @param vo
     */
    private void insertProfessionalSkills(FullResumeVO vo, String resumeId, String personId) {
        List<FullResumeProfessionalSkillsVO> professionalSkillsList = vo.getProfessionalSkillsList();
        if (StringUtil.isNullOrEmpty(professionalSkillsList)) {
            return;
        }
        professionalSkillsList.stream().forEach(item -> {
            try {
                ResumeProfessionalSkillsExt domain = new ResumeProfessionalSkillsExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);

                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());

                resumeProfessionalSkillsService.insert(domain);
            } catch (SkException e) {
                e.printStackTrace();
            }


        });

    }

    /**
     * 培训经历
     *
     * @param vo
     */
    private void insertCapabilityLabel(FullResumeVO vo, String resumeId, String personId) {
        List<FullResumeCapabilityLabelVO> capabilityLabelList = vo.getCapabilityLabelList();
        if (StringUtil.isNullOrEmpty(capabilityLabelList)) {
            return;
        }
        capabilityLabelList.stream().forEach(item -> {
            try {
                ResumeCapabilityLabelExt domain = new ResumeCapabilityLabelExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);

                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());


                resumeCapabilityLabelService.insert(domain);
            } catch (SkException e) {
                e.printStackTrace();
            }


        });

    }

    /**
     * 培训经历
     *
     * @param vo
     */
    private void insertTrainingExperience(FullResumeVO vo, String resumeId, String personId) {
        List<FullResumeTrainingExperienceVO> trainingExperienceList = vo.getTrainingExperienceList();
        if (StringUtil.isNullOrEmpty(trainingExperienceList)) {
            return;
        }
        trainingExperienceList.stream().forEach(item -> {
            try {
                ResumeTrainingExperienceExt domain = new ResumeTrainingExperienceExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);
                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());


                resumeTrainingExperienceService.insert(domain);
            } catch (SkException e) {
            }


        });

    }

    /**
     * 项目经历
     *
     * @param vo
     */
    private void insertProjectExperience(FullResumeVO vo, String resumeId, String personId) {
        List<FullResumeProjectExperienceVO> projectExperienceList = vo.getProjectExperienceList();
        if (StringUtil.isNullOrEmpty(projectExperienceList)) {
            return;
        }
        projectExperienceList.stream().forEach(item -> {
            try {
                ResumeProjectExperienceExt domain = new ResumeProjectExperienceExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);
                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());

                resumeProjectExperienceService.insert(domain);
            } catch (SkException e) {

            }


        });


    }

    /**
     * 证书
     *
     * @param vo
     */
    private void insertCertificate(FullResumeVO vo, String resumeId, String personId) {

        //证书
        List<FullResumeCertificateVO> certificateList = vo.getCertificateList();
        if (StringUtil.isNullOrEmpty(certificateList)) {
            return;
        }
        certificateList.stream().forEach(item -> {
            try {
                ResumeCertificateExt domain = new ResumeCertificateExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);
                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());


                resumeCertificateService.insert(domain);
            } catch (SkException e) {

            }


        });


    }

    /**
     * 工作经历
     *
     * @param vo
     */
    private void insertWorkExperience(FullResumeVO vo, String resumeId, String personId) {
        //工作经历
        List<FullResumeWorkExperienceVO> workExperienceList = vo.getWorkExperienceList();
        if (StringUtil.isNullOrEmpty(workExperienceList)) {
            return;
        }
        workExperienceList.stream().forEach(item -> {

            try {
                ResumeWorkExperienceExt domain = new ResumeWorkExperienceExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);
                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());


                resumeWorkExperienceService.insert(domain);
            } catch (SkException e) {

            }


        });


    }

    /**
     * 教育经历
     *
     * @param vo
     */
    private void insertEducation(FullResumeVO vo, String resumeId, String personId) {

        List<FullResumeEducationalExperienceVO> educationList = vo.getEducationList();
        if (StringUtil.isNullOrEmpty(educationList)) {
            return;
        }
        educationList.stream().forEach(item -> {

            try {
                ResumeEducationalExperienceExt domain = new ResumeEducationalExperienceExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);
                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                domain.setKzpStudentId(vo.getBasic().getKzpStudentId());
                resumeEducationalExperienceService.insert(domain);
            } catch (SkException e) {

            }


        });


    }

    /**
     * 求职意向
     *
     * @param vo
     */
    private void insertIntention(FullResumeVO vo, String resumeId, String personId) {

        List<FullResumeEmploymentIntentionVO> intentionList = vo.getIntentionList();
        if (StringUtil.isNullOrEmpty(intentionList)) {
            return;
        }

        intentionList.stream().forEach(item -> {

            try {
                ResumeEmploymentIntentionExt domain = new ResumeEmploymentIntentionExt();
                BeanUtils.copyPropertiesIgnoreNull(item, domain);
                domain.setResumesId(resumeId);
                domain.setOldResumesId(vo.getBasic().getOldResumesId());
                domain.setResumeCreateTime(vo.getBasic().getResumeCreateTime());
                resumeEmploymentIntentionService.insert(domain);
            } catch (SkException e) {

            }


        });


    }

    private void initCityPcasArray() {

        streetList = FileUtil.readInFile(fileConfig.getRoot() + File.separator + "city-pcas.json", Street.class);
        System.out.println(streetList);

    }

    private String getCityByCode(String code) {

        for (Street province : streetList) {
            String provinceName = province.getName();
            String provinceCode = province.getName();

            if (provinceCode.equalsIgnoreCase(code)) {
                return provinceName;
            }

            if (StringUtil.isNotObjEmpty(province.getChildren())) {
                for (Street city : province.getChildren()) {
                    String cityName = city.getName();
                    String cityCode = city.getCode();

                    if (cityCode.equalsIgnoreCase(code)) {
                        return provinceName + "-" + cityName;
                    }


                    if (StringUtil.isNotObjEmpty(city.getChildren())) {
                        for (Street area : city.getChildren()) {
                            String areaName = area.getName();
                            String areaCode = area.getCode();
                            if (areaCode.equalsIgnoreCase(code)) {
                                return provinceName + "-" + cityName + "-" + areaName;
                            }
                            if (StringUtil.isNotObjEmpty(area.getChildren())) {
                                for (Street street : area.getChildren()) {
                                    String streetName = street.getName();
                                    String streetCode = street.getCode();
                                    if (streetCode.equalsIgnoreCase(code)) {
                                        return provinceName + "-" + cityName + "-" + areaName + "-" + streetName;
                                    }

                                }


                            }

                        }

                    }


                }


            }


        }

        return code;

    }


    /**
     * 简历基础信息
     *
     * @param vo
     */
    private ResumeBasicExt insertResumeBasic(FullResumeVO vo) {
        try {

            ResumeBasicExt resumeBasic = new ResumeBasicExt();
            BeanUtils.copyPropertiesIgnoreNull(vo.getBasic(), resumeBasic);

            resumeBasic.setLivePlace(getCityByCode(resumeBasic.getLivePlace()));
            resumeBasic.setBirthPlace(getCityByCode(resumeBasic.getBirthPlace()));


           /* if (StringUtil.isNotObjEmpty(resumeBasic.getMobile())) {
                PersonSearchExt personSearch = PersonSearchExt.getInstance();
                personSearch.setPhoneEq(resumeBasic.getMobile());
                int count = personService.getCountBySearch(personSearch);
                //说明手机号码存在，就当他已经添加过
                if (count > 0) {
                    return null;
                }


            }*/


            PersonExt person = new PersonExt();
            person.setId(IdGen.uuid());
            person.setTruename(resumeBasic.getTruename());
            person.setPhone(resumeBasic.getMobile());
            person.setIdcard(resumeBasic.getIdcard());
            String personId = person.getId();

            log.info("yy person insrt before");
            personService.insert(person);
            log.info("yy person insrt end");
            resumeBasic.setPersonId(personId);
            log.info("yy basic insrt before");
            resumeBasicService.insert(resumeBasic);
            log.info("yy basic insrt end");
            return resumeBasic;

        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;


    }


}
